package com.wyh.service.serviceImpl.feemanagementserviceimpl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyh.domain.dto.feemanagementdto.ResourceFeeDTO;
import com.wyh.domain.dto.feemanagementdto.ResourcePhoneOrNameDTO;
import com.wyh.domain.po.feemanagementpo.*;
import com.wyh.domain.vo.feemanagementvo.BuildingunitNameAndIdVO;
import com.wyh.mapper.feemanagementmapper.BuildingunitsMapper;
import com.wyh.mapper.feemanagementmapper.ProjectMapper;
import com.wyh.service.feemanagementservice.*;


import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
@RequiredArgsConstructor
public class BuildingunitsServiceImpl extends ServiceImpl<BuildingunitsMapper, BuildingUnit> implements IBuildingunitsService {

    private final ResourceServiceImpl resourceService;

    private final ProjectMapper projectMapper;

    private final IContractService contractService;

    private final ICustomerService customerService;

    private final IChargingService chargingService;

    private final BillService billService;
    private final BuildingunitsMapper buildingunitsMapper;

    @Override
    //根据客户账号管辖的楼盘
    public List<ProjectUnitNode> getPerjectes(String account) {
        List<ProjectUnitNode> projectUnitNodes = new ArrayList<>();
        List<Integer> developmentids = baseMapper.getBuildingUnitByAccount(account);
        List<Projectes> projectes = projectMapper.selectBatchIds(developmentids);

        for (Projectes projecte : projectes) {
            ProjectUnitNode projectUnitNode = new ProjectUnitNode();
            projectUnitNode.setProjectid(projecte.getId());
            projectUnitNode.setProjectname(projecte.getName());
            //查询每个楼盘下的楼栋集合
            List<BuildingUnit> buildingUnits = getBuildingUnits(projecte.getId());
            projecte.setBuildingUnits(buildingUnits);
            List<BuildingunitNameAndIdVO> nameAndIdVOS = BeanUtil.copyToList(buildingUnits, BuildingunitNameAndIdVO.class);
            projectUnitNode.setBuildingunitList(nameAndIdVOS);
            for (BuildingUnit buildingUnit : buildingUnits) {
                //查询每个楼栋下的楼层集合
                List<Layeres> layeres = getFloorsBybuildingId(buildingUnit.getId());
                buildingUnit.setLayeresList(layeres);
            }
            projectUnitNodes.add(projectUnitNode);
        }
        if(CollectionUtil.isEmpty(projectUnitNodes)){
            return Collections.emptyList();
        }
        return projectUnitNodes;
    }

    //根据楼盘id查询楼盘下的所有资源，具体到细
    @Override
    public List<Resourcees> getResourcesByProjectId(Long projectId) {
        //获取楼盘下的所有楼栋
        List<BuildingUnit> buildingUnits = getBuildingUnits(projectId);
        //获取楼栋集合的所有ids
        List<Integer> buildingIds = buildingUnits.stream().map(BuildingUnit::getId).collect(Collectors.toList());
        //根据楼栋ids查询所有楼层
        List<Layeres> layeres = new ArrayList<>();
        for (Integer buildingId : buildingIds) {
            List<Layeres> layeresList = getFloorsBybuildingId(buildingId);
            layeres.addAll(layeresList);
        }
        //获取楼层集合的所有ids
        List<Integer> floorIds = layeres.stream().map(Layeres::getId).collect(Collectors.toList());
        //根据楼层ids查询所有资源
        List<Resourcees> resourcees = new ArrayList<>();
        for (Integer floorId : floorIds) {
            List<Resourcees> resourceesList = getResourcesByFloorId(floorId);
            resourcees.addAll(resourceesList);
        }
        if(CollectionUtil.isEmpty(resourcees)){
            return Collections.emptyList();
        }
        return resourcees;
    }

    @Override
    //根据楼栋id查询资源,具体到细
    public List<Resourcees> getResourcesByBuildingId(Integer buildingId) {
        //查询该楼栋下的楼层集合
        List<Layeres> floors = getFloorsBybuildingId(buildingId);
        //获取楼层集合的所有ids
        List<Integer> floorIds = floors.stream().map(Layeres::getId).collect(Collectors.toList());
        //根据楼层ids查询所有资源
        List<Resourcees> resourcees = new ArrayList<>();
        for (Integer floorId : floorIds) {
            List<Resourcees> resourceesList = resourceService.getResourceListByBuildingUtilId(floorId);
            resourcees.addAll(resourceesList);
        }
        if(CollectionUtil.isEmpty(resourcees)){
            return Collections.emptyList();
        }
        return resourcees;
    }


    // 根据楼层id查询该楼层下的资源
    public List<Resourcees> getResourcesByFloorId(Integer floorId) {
//        List<Layeres> layeres = getFloorsBybuildingId(floorId);
//        //获取楼层集合的所有ids
//        List<Integer> floorIds = layeres.stream().map(Layeres::getId).collect(Collectors.toList());
//        //根据楼层ids查询所有资源
//        List<Resourcees> resourcees = new ArrayList<>();
//        for (Integer floorId1 : floorIds) {
//            List<Resourcees> resourceesList = getResourcesByFloorId(floorId1);
//            resourcees.addAll(resourceesList);
//        }
        List<Resourcees> resourcees = baseMapper.getResources(floorId);
        if(CollectionUtil.isEmpty(resourcees)){
            return Collections.emptyList();
        }
        return resourcees;
    }

    public List<ResourcePhoneOrNameDTO> getResourceByNameOrPhoneNull(String nameOrPhone,Integer type,String account){
        //根据输入的客户名或者手机号在客户表查找客户id
        List<Integer> list = customerService.getCustomerIdByNameOrPhone(nameOrPhone);
        //根据客户id在客户合同中查找客户资源
        List<Resourcees> resourcees = contractService.getResorceByCustId(list);
        //判断资源的type
        List<Resourcees> filteredResourcees = new ArrayList<>();
        for (Resourcees resourcee : resourcees) {
            if (resourcee.getType() == type) {
                filteredResourcees.add(resourcee);
            }
        }
        // 现在filteredResourcees包含所有符合条件的元素，可以替换原来的列表
        resourcees = filteredResourcees;
        if(CollectionUtil.isEmpty(resourcees)){
            return Collections.emptyList();
        }

        //抽取资源的楼层id，并以楼层分组.楼层和资源的映射。
        Map<Integer, List<Resourcees>> layercollect = resourcees.stream().collect(Collectors.groupingBy(Resourcees::getBuildingid));
        //楼层和楼盘的映射,一个楼栋id对应一个楼盘id
        Map<Integer, Integer> layyercollectbuild = new HashMap<>();
        //根据楼层id查询该楼栋id
        Set<Integer> layerIds = layercollect.keySet();//楼层的集合
        List<Integer> projectIds = new ArrayList<>();
        //根据楼层id，获取楼层的父级楼盘id
        for (Integer layerId : layerIds) {
            Integer projectId = buildingunitsMapper.getProjectId(layerId);
            projectIds.add(projectId);
            layyercollectbuild.put(projectId,layerId);
        }
        //登录用户管辖的楼盘ids
        List<ProjectUnitNode> perjectes = getPerjectes(account);
        List<Long> collectProjectid = perjectes.stream().map(ProjectUnitNode::getProjectid).collect(Collectors.toList());
        List<Integer> projectIdsAll = collectProjectid.stream().map(Long::intValue).collect(Collectors.toList());

        //将projectIds和projectIdsAll进行交集，得到筛选后查询的楼盘ids
        projectIds.retainAll(projectIdsAll);

        //得到楼盘ids对应的楼层id
        List<Integer> layerIds1 = new ArrayList<>();
        for (Integer projectId : projectIds) {
            Integer i = layyercollectbuild.get(projectId);
            layerIds1.add(i);
        }
        //从楼层id得到对应的资源
        List<Resourcees> resourcees1 = new ArrayList<>();
        for (Integer layerId : layerIds1) {
            List<Resourcees> resourcees2 = layercollect.get(layerId);
            resourcees1.addAll(resourcees2);
        }

        //封装vo
        List<ResourcePhoneOrNameDTO> resourceFeeDTOList = new ArrayList<>();
        for (Resourcees resourcees2 : resourcees1) {
            ResourcePhoneOrNameDTO resourceFeeDTO = new ResourcePhoneOrNameDTO();
            //直接
            resourceFeeDTO.setId(resourcees2.getId());
            resourceFeeDTO.setIsvirtual(resourcees2.getIsvirtual());
            resourceFeeDTO.setRoom(resourcees2.getName());
            resourceFeeDTO.setStatus(resourcees2.getState());

            //间接
            List<Customers> customers = contractService.getCustomerByResourceId(resourcees2.getId());
            Integer i = isArrears(customers);
            resourceFeeDTO.setIsarrears(i);

            Integer customerid = contractService.getHomeownerByResourceId(resourcees2.getId());
            Customers customer = customerService.getById(customerid);
            resourceFeeDTO.setName(customer.getName());
            //加入
            resourceFeeDTOList.add(resourceFeeDTO);
        }
        return resourceFeeDTOList;
    }


    @Override
    // 根据楼盘（园区）id查询该楼盘（园区）下的楼栋
   public List<BuildingUnit> getBuildingUnits(Long projectId) {
        List<BuildingUnit> buildingUnits = lambdaQuery()
                .select(BuildingUnit::getId, BuildingUnit::getName)
                .eq(BuildingUnit::getParentid, projectId)
                .eq(BuildingUnit::getIsconnected, "Y")
                .eq(BuildingUnit::getState, 1)
                .eq(BuildingUnit::getType, 1)
                .list();
        if(CollectionUtil.isEmpty(buildingUnits)){
            return Collections.emptyList();
        }
        System.out.println(buildingUnits);
        return buildingUnits;
    }

    // 根据楼栋id查询该楼栋下的楼层
    public List<Layeres> getFloorsBybuildingId(Integer buildingId) {
        return baseMapper.getFloors(buildingId);
    }


    @Override
    //楼层查询资源
    public List<ResourceFeeDTO> getResourceListByBuildingUtilId(Integer floorId, Integer buildingid, Long projectid,Integer resourceType) {
        List<ResourceFeeDTO> resourceDTOS = new ArrayList<>();

        Projectes project = baseMapper.getProject(projectid);
        BuildingUnit buildingUnit = baseMapper.getBuildingUnit(buildingid);
        Layeres layeres = baseMapper.getLayers(floorId);
        List<Resourcees> resourceesList = getResourcesByFloorId(floorId);
        //筛选资源类型
        List<Resourcees> resourcees1 = new ArrayList<>();
        for (Resourcees resourcees : resourceesList) {
            if(resourcees.getType()==resourceType){
                resourcees1.add(resourcees);
            }
        }
        for (Resourcees resourcees : resourcees1) {
            ResourceFeeDTO dto = new ResourceFeeDTO();
            List<Customers> customers = contractService.getCustomerByResourceId(resourcees.getId());
            Integer i = isArrears(customers);
            dto.setIsarrears(i);
            dto.setHouses(project.getName());
            dto.setBuilding(buildingUnit.getName());
            dto.setFloor(layeres.getName());
            PageResourceDto(resourceDTOS, dto, resourcees);
        }
        return resourceDTOS;
    }

    @Override
    // 楼栋查询资源
    public List<ResourceFeeDTO> listResourcesByBuildingUtilId(Integer buildingid, Long projectid,Integer resourceType) {
        List<ResourceFeeDTO> resourceDTOS = new ArrayList<>();
        Projectes project = baseMapper.getProject(projectid);
        BuildingUnit buildingUnit = baseMapper.getBuildingUnit(buildingid);
        List<Resourcees> resourceesList = getResourcesByBuildingId(buildingid);
        List<Resourcees> resourcees1 = new ArrayList<>();
        for (Resourcees resourcees : resourceesList) {
            if(resourcees.getType()==resourceType){
                resourcees1.add(resourcees);
            }
        }
        for (Resourcees resourcees : resourcees1) {
            ResourceFeeDTO dto = new ResourceFeeDTO();
            List<Customers> customers = contractService.getCustomerByResourceId(resourcees.getId());
            Integer i = isArrears(customers);
            dto.setIsarrears(i);
            dto.setHouses(project.getName());
            dto.setBuilding(buildingUnit.getName());
            PageResourceDto(resourceDTOS, dto, resourcees);
        }
        return resourceDTOS;
    }

    @Override
    //楼盘查询资源dto
    public List<ResourceFeeDTO> listResourcesByProjectId(Long projectid,Integer resourceType) {
        List<ResourceFeeDTO> resourceDTOS = new ArrayList<>();

        Projectes project = baseMapper.getProject(projectid);
        List<Resourcees> projectId = getResourcesByProjectId(projectid); // 确保这个方法存在并返回正确的数据
        List<Resourcees> resourcees1 = new ArrayList<>();
        for (Resourcees resourcees : projectId) {
            if(resourcees.getType()==resourceType){
                resourcees1.add(resourcees);
            }
        }
        for (Resourcees resourcees : resourcees1) {
            ResourceFeeDTO dto = new ResourceFeeDTO();
            //判断是否为欠费资源
            List<Customers> customers = contractService.getCustomerByResourceId(resourcees.getId());
            Integer i = isArrears(customers);
            dto.setIsarrears(i);
            //设置楼盘名
            dto.setHouses(project.getName());
            //设置
            PageResourceDto(resourceDTOS, dto, resourcees);
        }
        return resourceDTOS;
    }

    private void PageResourceDto(List<ResourceFeeDTO> resourceDTOS, ResourceFeeDTO dto, Resourcees resourcees) {
        Integer customerid = contractService.getHomeownerByResourceId(resourcees.getId());
        Customers customer = customerService.getById(customerid);
        dto.setName(customer.getName());
        dto.setRoom(resourcees.getName());
        dto.setIsvirtual(resourcees.getIsvirtual());
        dto.setId(resourcees.getId());
//        List<FeeFormVO> feeFormVOList = chargingService.getFeeFormByResourceId(resourcees.getId());
//        dto.setRecords(feeFormVOList);
        dto.setStatus(resourcees.getState());
        resourceDTOS.add(dto);
    }

    public Integer isArrears(List<Customers> customers) {
        //获取客户的ids
        List<Integer> customerIds = customers.stream().map(Customers::getId).collect(Collectors.toList());
        //根据客户ids查询所有的账单，判断账单里的欠费状态，发现任意一个欠费状态为1，则返回1，否则返回0
        return billService.isBillOverdue(customerIds);
    }


}
